package com.own.component.elastic.constant;

import co.elastic.clients.elasticsearch._types.aggregations.CalendarInterval;
import lombok.Builder;
import lombok.Getter;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;

/**
 * CalendarIntervalConstant
 *
 * @author chenxueli
 * @date 2024-05-08 03:29:00
 */
public class CalendarIntervalConstant {

    /**
     * 时间统计范围
     */
    public static final Map<String, CalendarInterval> MAP = Map.of(
            "second", CalendarInterval.Second,
            "minute", CalendarInterval.Minute,
            "hour", CalendarInterval.Hour,
            "day", CalendarInterval.Day,
            "week", CalendarInterval.Week,
            "month", CalendarInterval.Month,
            "quarter", CalendarInterval.Quarter,
            "year", CalendarInterval.Year
    );
    /**
     * 时间统计范围的格式
     */
    public static final Map<String, String> FORMAT_MAP = Map.of(
            "second", "yyyy-MM-dd HH:mm:ss",
            "minute", "yyyy-MM-dd HH:mm",
            "hour", "yyyy-MM-dd HH",
            "day", "yyyy-MM-dd",
            "week", "yyyy-MM-dd",
            "month", "yyyy-MM",
            "quarter", "yyyy-MM",
            "year", "yyyy"
    );
    private static final ZoneOffset DEFAULT_ZONE_OFFSET = ZoneOffset.of("+8");
    private static final DateHistogramInfo DEFAULT_DATE_HISTOGRAM_INFO = DateHistogramInfo.builder().interval(CalendarInterval.Day).format("yyyy-MM-dd").build();

    private static final Map<String, DateHistogramInfo> DATE_HISTOGRAM_INFO_MAP = Map.of(
            "second", DateHistogramInfo.builder().interval(CalendarInterval.Second).format("yyyy-MM-dd HH:mm:ss").build(),
            "minute", DateHistogramInfo.builder().interval(CalendarInterval.Minute).format("yyyy-MM-dd HH:mm").build(),
            "hour", DateHistogramInfo.builder().interval(CalendarInterval.Hour).format("yyyy-MM-dd HH").build(),
            "day", DateHistogramInfo.builder().interval(CalendarInterval.Day).format("yyyy-MM-dd").build(),
            "week", DateHistogramInfo.builder().interval(CalendarInterval.Week).format("yyyy-MM-dd").build(),
            "month", DateHistogramInfo.builder().interval(CalendarInterval.Month).format("yyyy-MM").build(),
            "quarter", DateHistogramInfo.builder().interval(CalendarInterval.Quarter).format("yyyy-MM").build(),
            "year", DateHistogramInfo.builder().interval(CalendarInterval.Year).format("yyyy").build()
    );

    /**
     * 根据开始时间和结束时间获取时间统计范围
     *
     * @param startTime 开始时间
     * @param dateTime  结束时间
     * @return 时间统计范围
     */
    public static CalendarInterval getByTimeRange(LocalDateTime startTime, LocalDateTime dateTime) {
        var diff = dateTime.toEpochSecond(DEFAULT_ZONE_OFFSET) - startTime.toEpochSecond(DEFAULT_ZONE_OFFSET);
        if (diff < 60) {
            return CalendarInterval.Second;
        }
        if (diff < 3600) {
            return CalendarInterval.Minute;
        }
        if (diff < 86400) {
            return CalendarInterval.Hour;
        }
        if (diff < 604800) {
            return CalendarInterval.Day;
        }
        if (diff < 2592000) {
            return CalendarInterval.Week;
        }
        if (diff < 31536000) {
            return CalendarInterval.Month;
        }
        if (diff < 31536000 * 4) {
            return CalendarInterval.Quarter;
        }
        return CalendarInterval.Year;
    }

    /**
     * 获取时间统计范围信息
     *
     * @param interval 时间统计范围
     * @return 时间统计范围信息
     */
    public static DateHistogramInfo getDateHistogramInfo(String interval) {
        return DATE_HISTOGRAM_INFO_MAP.getOrDefault(interval, DEFAULT_DATE_HISTOGRAM_INFO);
    }

    @Builder
    @Getter
    public static class DateHistogramInfo implements Serializable {
        private CalendarInterval interval;
        private String format;
    }

}
